/*
 *  Copyright (C) 2010 takaji
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package examples;

import examples.helpers.Worker;
import dakside.csv.CSVException;
import dakside.csv.CSVFileReader;
import dakside.csv.CSVFileWriter;
import dakside.csv.CSVLine;
import java.io.FileNotFoundException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Example 4: Create a sample CSV file and save to system temp folder.<br/>
 * After that, we create 10 threads to access that CSV file to read lines<br/>
 * and write to another file (at the same time).
 * @author Takaji
 */
public class Example4 {

    /**
     * @param args  the command line arguments
     */
    public static void main(String[] args) {
        String fs = System.getProperty("file.separator");
        String filein = System.getProperty("user.home") + fs + "testbig.csv";
        String fileout = System.getProperty("user.home") + fs + "testbig_clone.csv";

        //create sample data for testing
        createTestData(filein);
        //test multiple thread access
        testMultiThreadReadAndWrite(filein, fileout);
    }

    /**
     * Create sample data for multiple-thread testing
     * 
     * @param file
     */
    public static void createTestData(String file) {
        //Create a sample CSV data by code
        System.out.println("Creating sample data...");
        System.out.println("Sample data is located at:");
        int testLines = 10000; //test lines
        System.out.println(file);
        /*
         * Here, we create each CSV line, then immediately write to file,
         * so we don't have to keep so many data in memory. Good tips if you
         * want to write a large amount of data
         */
        CSVFileWriter writer = new CSVFileWriter(file);
        for (int i = 0; i < testLines; i++) {
            //add some sample columns
            CSVLine line = new CSVLine().add("Person " + i).
                    add(i).
                    add(i * 10).
                    add("Street " + i).
                    add(i % 2 == 0);
            writer.writeLine(line);
        }
        writer.close(); //writer.flush() is automatically called when close()
        System.out.println("Done create sample file!");
    }

    /**
     * Test read and write CSV file by multiple threads
     * 
     * @param filein
     * @param fileout
     * @throws FileNotFoundException
     */
    private static void testMultiThreadReadAndWrite(String filein, String fileout) {
        System.out.println("Sample multiple thread access 1 CSV instance for reading and writing");
        System.out.println("Read from: " + filein);
        System.out.println("Write to : " + fileout);
        // Multiple-thread reading & writing
        Thread[] workers = new Thread[10]; // we create 10 workers

        // create 1 reader
        CSVFileReader reader;
        // and 1 writer
        CSVFileWriter writer;
        try {
            reader = new CSVFileReader(filein);
            writer = new CSVFileWriter(fileout);
        } catch (CSVException ex) {
            Logger.getLogger(Example4.class.getName()).log(Level.SEVERE, null,
                    ex);
            return;
        }

        // create 10 workers to do work
        for (int i = 0; i < workers.length; i++) {
            Worker worker = new Worker("Worker " + i, reader, writer, false);
            workers[i] = new Thread(worker);
        }

        // start all workers
        for (int i = 0; i < workers.length; i++) {
            workers[i].start();
        }
    }
}
